<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./lib/vue-2.4.0.js"></script>
    <link rel="stylesheet" href="./lib/bootstrap-3.3.7.css">
</head>

<body>
    <div id="app">

        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">添加品牌</h3>
            </div>
            <div class="panel-body form-inline">
                <label>
                    Id:
                    <input type="text" class="form-control" v-model="id">
                </label>
                <label>
                    Name:
                    <!-- 按键修饰符 -->
                    <!-- <input type="text" class="form-control" v-model="name" @keyup.enter="add"> -->

                    <!-- 自定义修饰符 F2 键盘 keyCodes 是 113 -->
                    <!-- <input type="text" class="form-control" v-model="name" @keyup.113="add"> -->

                    <!-- 自定义修饰符 创建一个 f2的别名 -->
                    <input type="text" class="form-control" v-model="name" @keyup.f2="add">

                </label>
                <!-- 在vue中，使用事件绑定机制，为元素指定 -->
                <input type="button" value="添加" class="btn btn-primary" @click="add()">

                <label>
                    搜索名称关键字：
                    <!-- 注意：Vue中所有的指令，在调用的时候，都以 v-开头 -->
                    <input type="text" class="form-control" v-model="keywords" v-focus>
                </label>
            </div>
        </div>

        <table class="table table-bordered table-hover table-striped">
            <thead>
                <tr>
                    <th>Id</th>
                    <th>Name</th>
                    <th>Ctime</th>
                    <th>Option</th>
                </tr>
            </thead>
            <tbody>
                <!-- <tr v-for="item in list" :key="item.id">
                    <td>{{item.id}}</td>
                    <td v-text="item.name"></td>
                    <td>{{item.ctime}}</td>
                    <td><a href="" @click.prevent="del(item.id)">删除</a></td>
                </tr> -->

                <!-- 之前， v-for 中的数据，都是直接从 data 上的list中直接渲染过来的 -->
                <!-- 现在，我们自顶一个search方法，同时，把所有的关键字，通过传参的形式，传递给了search方法 -->
                <!-- 在search 方法内部,通过执行for循环，把所有符合搜索关键字的数据，保存到一个新数组中，返回 -->
                <tr v-for="item in search(keywords)" :key="item.id">
                    <td>{{item.id}}</td>
                    <td v-text="item.name"></td>
                    <td>{{item.ctime | dateFormat()}}</td>
                    <!-- 加上.prevent 阻止点击后默认刷新 -->
                    <td><a href="" @click.prevent="del(item.id)">删除</a></td>
                </tr>

            </tbody>
        </table>

    </div>

    <div id="app2">
        <h3 v-color="'red'" v-fontweight="1000" v-fontsize="'30px'">{{dt|dateFormat}}</h3>
    </div>

    <script>
        // 全局的过滤器，进行时间的格式化
        Vue.filter('dateFormat', function (dateStr, pattern = "") {
            var dt = new Date(dateStr)

            var y = dt.getFullYear()
            var m = dt.getMonth() + 1
            var d = dt.getDate()

            // return y + '-' + m + '-' + d
            if (pattern.toLowerCase() === 'yyyy-mm-dd') {
                return `${y}-${m}-${d}`
            } else {
                var hh = dt.getHours()
                var mm = dt.getMinutes()
                var ss = dt.getSeconds()

                return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
            }
        })

        // 自定义全局按键修饰符
        Vue.config.keyCodes.f2 = 113

        // 使用 vue.directive() 定义全局的指令 v-focus
        // 其中：参数1：指令的名称，注意，在定义的时候，指令的名称前面，不需要加 v- 前缀，
        // 但是：在调用的时候，必须在指令名称前加上v-前缀来进行调用
        // 参数2：是一个对象，这个对象身上，有一些指令相关的函数，这些函数可以在特定的阶段，执行相关的操作
        Vue.directive('focus', {
            bind: function (el) { // 每当指令绑定到元素上的时候，会立即执行这个bind函数，只执行一次【与样式有关的】
                // 注意：在每个函数中，第一个参数，永远是el,表示被绑定了指令的那个元素，这个el参数，是一个原生的JS对象
                // 在元素刚绑定了指令的时候，还没有插入到DOM中去，这时候，调用focus方法没有作用
                // 因为，一个元素，只有插入DOM之后，才能获取焦点
                // el.focus()
            },
            inserted: function (el) { // inserted 表示元素 插入到DOM中的时候，会执行inserted函数【触发1次】【与行为有关的】
                el.focus()
            },
            updated: function (el) { // 当VNode更新的时候，会执行updated，可能会触发多次

            }
        })

        // 自定义一个 设置字体颜色的指令
        Vue.directive('color', {
            // 样式，只要通过指令绑定给了元素，不管这个元素有没有被插入到页面中去，这个元素肯定有了一个内联的样式
            // 将来元素肯定会显示到页面中，这时候，浏览器的渲染引擎必然会解析样式，应用给这个元素
            bind: function (el, binding) {
                // el.style.color = 'red'
                // 和样式相关的操作，一般都可以用bind执行

                el.style.color = binding.value
            }
        })

        //创建Vue实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {
                id: '',
                name: '',
                keywords: '',
                list: [{
                        id: 1,
                        name: '奔驰',
                        ctime: new Date()
                    },
                    {
                        id: 2,
                        name: '宝马',
                        ctime: new Date()
                    }
                ]
            },
            methods: {
                add() { // 添加的方法
                    if (this.id == null || this.id.trim() == '') return

                    var car = {
                        id: this.id,
                        name: this.name,
                        ctime: new Date()
                    }
                    this.list.push(car)
                    this.id = this.name = ''
                },
                del(id) { // 根据Id删除数据
                    // 分析：
                    // 1、如何根据Id，找到要删除这一项的索引
                    // 2、如果找到索引了，直接调用 数组的 splice 方法

                    // 第一种删除方式
                    /* this.list.some((item, i) => {
                        if (item.id == id) {
                            this.list.splice(i, 1)
                            // 在数组的some方法中，如果return true 就会立即终止这个数组的后续循环
                            return true;
                        }
                    }) */

                    // 第二种删除方式,通过findIndex找到数据对应的索引，然后再删除
                    var index = this.list.findIndex(item => {
                        if (item.id == id) {
                            return true;
                        }
                    })
                    this.list.splice(index, 1)
                },
                search(keywords) { // 根据关键字，进行数据的搜索
                    // 第一种方式
                    /* var newList = []
                    this.list.forEach(item => {
                        if (item.name.indexOf(keywords) != -1) {
                            newList.push(item)
                        }
                    })
                    return newList */

                    // 第二种方式
                    // 注意：forEach some fifter findIndex 这些都属于数组的新方法
                    // 都会对数组中的每一项，进行遍历，执行相关的操作
                    return this.list.filter(item => {
                        // 注意：ES6中，为字符串提供了一个新方法，叫做 String.prototype.includes('要包含的字符串')
                        // 如果包含，则返回true,否则返回 false
                        //
                        if (item.name.includes(keywords)) {
                            return item
                        }
                    })
                }
            }
        });

        var vm2 = new Vue({
            el: '#app2',
            data: {
                dt: new Date()
            },
            methods: {},
            filters: { // 定义私有过滤器 过滤器有两个条件 【过滤器名称 和 处理函数】
                // 过滤器调用的时候，采用的是就近原则，如果私有过滤器和全局过滤器名称一致了，这时候 优先调用私有过滤器
                // 字符串的padStart 自动补齐
                dateFormat: function (dateStr, pattern = "") {
                    var dt = new Date(dateStr)

                    var y = dt.getFullYear()
                    var m = (dt.getMonth() + 1).toString().padStart(2, '0')
                    var d = dt.getDate().toString().padStart(2, '0')

                    // return y + '-' + m + '-' + d
                    if (pattern.toLowerCase() === 'yyyy-mm-dd') {
                        return `${y}年${m}月${d}日`
                    } else {
                        var hh = dt.getHours().toString().padStart(2, '0')
                        var mm = dt.getMinutes().toString().padStart(2, '0')
                        var ss = dt.getSeconds().toString().padStart(2, '0')

                        return `${y}年${m}月${d}日 ${hh}时${mm}分${ss}秒`
                    }
                }
            },
            directives: { // 自定义私有指令
                'fontweight': { // 设置字体粗细的
                    bind: function (el, binding) {
                        el.style.fontWeight = binding.value
                    }
                },
                'fontsize': function (el, binding) { // 注意：这个function等同于把代码写到了 bind和update中去
                    el.style.fontSize = parseInt(binding.value) + 'px'
                }
            }
        })
    </script>
</body>

</html>